<!DOCTYPE html>
<html>
    
<head>
    <meta charset="utf-8">
    
    <title>一文彻底了解Android自定义控件1 | ApocalypseBlog</title>
    <canvas id="header_canvas"style="position:absolute;bottom:0"></canvas> 
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

    

    

    

    

    
<link rel="stylesheet" href="/dist/build.css?v=1.14.0.css">

    <script src="/javascripts/bubble.js"></script>
    <script>
        window.isPost = true
        window.aomori = {
            
            
        }
        window.aomori_logo_typed_animated = false
        window.aomori_search_algolia = false

    </script>
<script>
    ((window.gitter = {}).chat = {}).options = {
      room: 'ApocalypseBlog/Apocalypse'
    };
  </script>
  <script src="https://sidecar.gitter.im/dist/sidecar.v1.js" async defer></script>
<meta name="generator" content="Hexo 5.3.0"></head>
<!--DaoVoice服务http://blog.daovoice.io/-->

    <script>(function (i, s, o, g, r, a, m) {
        i['DaoVoiceObject'] = r;
        i[r] = i[r] ||
          function () {
            (i[r].q = i[r].q || []).push(arguments);
          };
        i[r].l = 1 * new Date();
        a = s.createElement(o);
        m = s.getElementsByTagName(o)[0];
        a.async = 1;
        a.src = g;
        a.charset = 'utf-8';
        m.parentNode.insertBefore(a, m);
      })(window, document, 'script', ('https:' === document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/b00f5052.js", 'daovoice');
      daovoice('init', {
        app_id: "b00f5052",
      });
      daovoice('update');
    </script>
  
<body>

    <div class="container">
    <header class="header">
        <div class="header-type">
            
            <div class="header-type-inner">
                
                    <a class="header-type-title" href="/">ApocalypseBlog</a>
                
    
                
            </div>
        </div>
        <div class="header-menu">
            <div class="header-menu-inner">
                
            </div>
            <div class="header-menu-social">
                
            </div>
        </div>

        <div class="header-menu-mobile">
            <div class="header-menu-mobile-inner" id="mobile-menu-open">
                <i class="icon icon-menu"></i>
            </div>
        </div>
    </header>

    <div class="header-menu-mobile-menu">
        <div class="header-menu-mobile-menu-bg"></div>
        <div class="header-menu-mobile-menu-wrap">
            <div class="header-menu-mobile-menu-inner">
                <div class="header-menu-mobile-menu-close" id="mobile-menu-close">
                    <i class="icon icon-cross"></i>
                </div>
                <div class="header-menu-mobile-menu-list">
                    
                </div>
            </div>
        </div>
    </div>

</div>

    <div class="container">
        <div class="main">
            <section class="inner">
                <section class="inner-main">
                    <div class="post">
    <article id="post-ckk6o6aut000b7knycrzl90pl" class="article article-type-post" itemscope
    itemprop="blogPost">

    <div class="article-inner">

        
          
        
        
        

        
        <header class="article-header">
            
  
    <h1 class="article-title" itemprop="name">
      一文彻底了解Android自定义控件1
    </h1>
  

        </header>
        

        <div class="article-more-info article-more-info-post hairline">

            <div class="article-date">
  <time datetime="2020-06-11T21:37:09.000Z" itemprop="datePublished">2020-06-12</time>
</div>

            

            

            

        </div>

        <div class="article-entry post-inner-html hairline" itemprop="articleBody">
            <h3 id="AndroidView体系"><a href="#AndroidView体系" class="headerlink" title="AndroidView体系"></a>AndroidView体系</h3><p>了解android的View体系，才知道后面我们步骤写Android自定义控件做准备。</p>
<p>要明白<code>View</code>和<code>ViewGroup</code>。</p>
<p>要能判断常用的控件是属于<code>View</code>还是<code>ViewGrop</code>，接着才有自己要写的控件属于<code>View</code>还是<code>ViewGroup</code>。</p>
<p>为什么呢？</p>
<p>因为自定义<code>View</code>跟自定义<code>ViewGroup</code>的步骤，套路不一样。</p>
<a id="more"></a>

<h3 id="Android自定义控件类型"><a href="#Android自定义控件类型" class="headerlink" title="Android自定义控件类型"></a>Android自定义控件类型</h3><p>Android自定义控件呢，我们可以分为三类：</p>
<ul>
<li>自定义View（包括对现有View的修改）;</li>
<li>自定义ViewGrop（包括对现有ViewGroup的修改）;</li>
<li>自定义ViewGrop;</li>
</ul>
<h3 id="自定义组合控件例子"><a href="#自定义组合控件例子" class="headerlink" title="自定义组合控件例子"></a>自定义组合控件例子</h3><p>自定义组合控件，其实就是把多个现在有控件整合在一起，把复杂的操作封装起来，把简单的操作暴露出去。</p>
<p>比如说我们要做以下这个控件：</p>
<p><img src="http://user-gold-cdn.xitu.io/2020/6/6/172877873e858952?imageView2/0/w/1280/h/960/format/webp/ignore-error/1" alt="img"></p>
<p>当然可以重头开始绘制，从无到有。</p>
<p>我们也可以使用两个<code>button</code> + 一个<code>TextView</code>或者<code>EditText</code>组合起来。</p>
<p>然后把复杂的逻辑封装起来，比如说，上限和下限的判断，比如说增加梯度，比如说阀值，达到一定的值会改变颜色之类的。这些复杂的操作封装起来。对外只暴露数据变会的回调通知和设置数值/获取数值的方法即可。</p>
<p>别人拿到你的控件，不关心怎么实现，只关心使用即可。</p>
<h3 id="自定义View例子"><a href="#自定义View例子" class="headerlink" title="自定义View例子"></a>自定义View例子</h3><p>自定义View，什么是View，从控件的角度来理解，我们可以这样判断。如果控件里没有孩子的，没有子View的，就是View，比如说<code>Button</code>,<code>TextView</code>,<code>ProgressBar</code>,<code>ImageView</code>,这些都是<code>View</code>.</p>
<h3 id="自定义ViewGroup例子"><a href="#自定义ViewGroup例子" class="headerlink" title="自定义ViewGroup例子"></a>自定义ViewGroup例子</h3><p>自定义ViewGrop，什么是ViewGroup,用来包含孩子的，控制子View的摆放的，是容器。ViewGrop里还可以包含着ViewGroup和View。比如说，LinearLayout,RetiveLayout,RecyclerView,ListView,ViewPager…这些都是ViewGrop。</p>

        </div>

    </div>

    

    

    

    

    

    
<nav class="article-nav">
  
    <a href="/2020/06/12/%E4%B8%80%E6%96%87%E5%BD%BB%E5%BA%95%E4%BA%86%E8%A7%A3Android%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B62/" id="article-nav-newer" class="article-nav-link-wrap">
      <div class="article-nav-caption">下一篇</div>
      <div class="article-nav-title">
        
          一文彻底了解Android自定义控件2
        
      </div>
    </a>
  
  
    <a href="/2020/06/12/Android-%E5%A4%8D%E6%9D%82%E7%9A%84%E5%88%97%E8%A1%A8%E8%A7%86%E5%9B%BE%E6%96%B0%E5%86%99%E6%B3%95-MultiType/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-caption">上一篇</div>
      <div class="article-nav-title">Android 复杂的列表视图新写法 MultiType</div>
    </a>
  
</nav>


    <section class="share">
        <div class="share-title">分享</div>
        <a class="share-item" target="_blank"
            href="https://twitter.com/share?text=一文彻底了解Android自定义控件1 - ApocalypseBlog&url=http://example.com/2020/06/12/%E4%B8%80%E6%96%87%E5%BD%BB%E5%BA%95%E4%BA%86%E8%A7%A3Android%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B61/">
            <box-icon type='logo' name='twitter'></box-icon>
        </a>
        <a class="share-item" target="_blank"
            href="https://www.facebook.com/sharer.php?title=一文彻底了解Android自定义控件1 - ApocalypseBlog&u=http://example.com/2020/06/12/%E4%B8%80%E6%96%87%E5%BD%BB%E5%BA%95%E4%BA%86%E8%A7%A3Android%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B61/">
            <box-icon name='facebook-square' type='logo' ></box-icon>
        </a>
        <!-- <a class="share-item" target="_blank"
            href="https://service.weibo.com/share/share.php?title=一文彻底了解Android自定义控件1 - ApocalypseBlog&url=http://example.com/2020/06/12/%E4%B8%80%E6%96%87%E5%BD%BB%E5%BA%95%E4%BA%86%E8%A7%A3Android%E8%87%AA%E5%AE%9A%E4%B9%89%E6%8E%A7%E4%BB%B61/&pic=">
            <div class="n-icon n-icon-weibo"></div>
        </a> -->
    </section>

</article>









</div>
                </section>
            </section>

             
            <aside class="sidebar">
            
                
            </aside>
        </div>
    </div>

    <footer class="footer">
    <div class="footer-wave">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1440 320"><path fill="#3c4859" fill-opacity="1" d="M0,160L60,181.3C120,203,240,245,360,240C480,235,600,181,720,186.7C840,192,960,256,1080,261.3C1200,267,1320,213,1380,186.7L1440,160L1440,320L1380,320C1320,320,1200,320,1080,320C960,320,840,320,720,320C600,320,480,320,360,320C240,320,120,320,60,320L0,320Z"></path></svg>
    </div>

    <div class="footer-wrap">
        <div class="footer-inner"> 
            ApocalypseBlog &copy; 2021<br>
            Powered By Hexo · Theme By <a href="https://github.com/lh1me/hexo-theme-aomori" target="_blank">Aomori</a>
        </div>
    </div>

</footer>




<script src="/dist/build.js?1.14.0.js"></script>


<script src="/dist/custom.js?1.14.0.js"></script>









</body>

</html>